package com.gis3c.sys.web.controller;

import com.gis3c.sys.entry.po.Token;
import com.gis3c.sys.entry.vo.*;
import com.gis3c.sys.service.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.*;

/**
 * Created by hukekuan on 2017/9/4.
 */

@Controller
@RequestMapping(value = "/sys")
public class SystemController {
    @Value("#{configProperties['sys.domainId']}")
    protected String domainId;

    @Autowired private UserService userService;
    @Autowired private RoleService roleService;
    @Autowired private OrgService orgService;
    @Autowired private MenuService menuService;
    @Autowired private AppService appService;
    @Autowired private DictionaryService dictionaryService;

    /************************************组织机构管理 start***************************************/
    @RequestMapping(value = "/user/orgadd")
    public String orgAdd(@RequestParam(value ="parentid") String parentid,Model model){
        model.addAttribute("parentid",parentid);
        return "sys/user/orgedit";
    }

    @RequestMapping(value = "/user/orgcreate",method = RequestMethod.POST)
    @ResponseBody
    public Object createOrg(@ModelAttribute("org") OrganizationModel org){
        Map<String,Object> result = new HashMap<>();
        if(org != null){
            orgService.createOrg(org);
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/user/orglist",method = RequestMethod.GET)
    @ResponseBody
    public Object orgList(){
        return orgService.orgList();
    }
    /************************************组织机构管理 end***************************************/



    /************************************用户管理 satrt******************************************/
    /**
     * 用户管理页面
     * @return
     */
    @RequestMapping(value = "/user/usermanage")
    public String userManage(){
        return "sys/user/usermanage";
    }

    /**
     * 用户添加页面
     * @return
     */
    @RequestMapping(value = "/user/useradd")
    public String userAdd(@RequestParam(value = "orgid",required = true) String orgId, Model model){
        model.addAttribute("orgId",orgId);
        return "sys/user/useredit";
    }

    /**
     * 用户编辑页面
     * @param userid
     * @return
     */
    @RequestMapping(value = "/user/useredit")
    public ModelAndView userEdit(@RequestParam(value="userid", required=true) String userid){
        UserModel queryUser = userService.findByUserId(userid);
        ModelAndView mv = new ModelAndView("sys/user/useredit");
        mv.addObject("user",queryUser);
        return mv;
    }

    /**
     * 用户列表
     * @return
     */
    @RequestMapping(value = "/user/userlist",method = RequestMethod.GET)
    @ResponseBody
    public Map<String,Object> userList(
            @RequestParam(value = "limit", required=true) int pagesize,
            @RequestParam(value = "page", required=true) int currentpage,
            @RequestParam(value = "orgid", required = false) String orgId){
        Map<String,Object> result = new HashMap<String,Object>();

        if(orgId != null && !"0".equals(orgId)){
            result.put("count",userService.usersCountByOrgId(orgId));
            result.put("data",userService.findUsersByOrgId(orgId,pagesize,currentpage));
        }else {
            result.put("count",userService.allUsersCount());
            result.put("data", userService.allUsersByPage(pagesize,currentpage));
        }

        result.put("code",0);
        result.put("msg","");
        return result;
    }

    /**
     * 插入一个用户数据
     * @return
     */
    @RequestMapping(value = "/user/usercreate",method = RequestMethod.POST)
    @ResponseBody
    public Object userCreate(@ModelAttribute("user") UserModel user){
        Map<String,Object> result = new HashMap<>();
        if(user != null){
            userService.createUser(user);

            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    /**
     * 用户编辑
     * @param user
     * @return
     */
    @RequestMapping(value = "/user/userupdate",method = RequestMethod.POST)
    @ResponseBody
    public Object userUpdate(@ModelAttribute("user") UserModel user){
        Map<String,Object> result = new HashMap<>();
        if(user != null){
            userService.changePassword(user.getId(),user.getPassword());
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    /**
     * 用户删除
     * @param userIds
     * @return
     */
    @RequestMapping(value = "/user/userremove",method = RequestMethod.POST)
    @ResponseBody
    public Object userRemove(@RequestBody String userIds){
        Map<String,Object> result = new HashMap<>();

        if(userIds != null){
            userService.deleteUsers(userIds.split(","));
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }
    /************************************用户管理 end******************************************/



    /************************************token管理 satrt******************************************/
    @RequestMapping(value = "/user/tokenmanage")
    public String tokenManage(
            @RequestParam(value = "userid", required = true) String userId,Model model){
        UserModel queryUser = userService.findByUserId(userId);
        Token queryToken = userService.findTokenByUserId(userId);

        model.addAttribute("userId",userId);
        model.addAttribute("userName",queryUser != null ? queryUser.getUsername():"");
        model.addAttribute("token",queryToken != null ? queryToken.getToken():"");
        model.addAttribute("secretKey",queryToken != null ? queryToken.getSecretKey():"");
        return "sys/user/tokenedit";
    }

    @RequestMapping(value = "/user/tokencreate", method = RequestMethod.POST)
    @ResponseBody
    public Object tokenCreate(@ModelAttribute("tokenModel") TokenModel tokenModel){
       Token createdToken =  userService.createToken(
               tokenModel.getUserId(),
               tokenModel.getSecretKey()
       );
       return new TokenModel(
               createdToken.getUserId(),
               createdToken.getSecretKey(),
               createdToken.getToken());
    }

    @RequestMapping(value = "/user/tokensave", method = RequestMethod.POST)
    @ResponseBody
    public Object tokenSave(@ModelAttribute("tokenModel") TokenModel tokenModel){
        Map<String,Object> result = new HashMap<>();
        result.put("status","error");

        Token updatedToken = new Token(
                tokenModel.getUserId(),
                tokenModel.getSecretKey(),
                tokenModel.getToken(),
                new Date()
        );
        int updatedNum = userService.updateToken(updatedToken);
        if(updatedNum == 1){
            result.put("status","OK");
        }

        return result;
    }
    /************************************ token管理 end ******************************************/



    /************************************ 角色管理 start ******************************************/
    /**
     * 角色管理页面
     * @return
     */
    @RequestMapping(value = "/user/rolemanage")
    public String roleManage(){
        return "sys/role/rolemanage";
    }

    /**
     * 角色添加页面
     * @return
     */
    @RequestMapping(value = "/user/roleadd")
    public String roleAdd(){
        return "sys/role/roleedit";
    }

    @RequestMapping(value = "/user/roleedit",method = RequestMethod.GET)
    public String roleEdit(@RequestParam(value="roleid", required=true) String roleid,Model model){
        RoleModel queryRole = roleService.FindRoleById(roleid);
        model.addAttribute("role",queryRole);
        return "sys/role/roleedit";
    }

    @RequestMapping(value = "/user/rolelist",method = RequestMethod.GET)
    @ResponseBody
    public Object roleList(
            @RequestParam(value = "limit", required=false) Integer pageSize,
            @RequestParam(value = "page", required=false) Integer currentPage){
        if(pageSize == null || currentPage == null){
            return roleService.RoleList(pageSize,currentPage);
        }
        Map<String,Object> result = new HashMap<>();
        result.put("count",roleService.RoleCount());
        result.put("data",roleService.RoleList(pageSize,currentPage));
        result.put("code",0);
        result.put("msg","");
        return result;
    }

    @RequestMapping(value = "/user/rolecreate",method = RequestMethod.POST)
    @ResponseBody
    public Object roleCreate(@ModelAttribute("role") RoleModel role){
        Map<String,Object> result = new HashMap<>();
        if(role != null){
            roleService.CreateRole(role);
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/user/roleupdate",method = RequestMethod.POST)
    @ResponseBody
    public Object roleUpdate(@ModelAttribute("role") RoleModel role){
        Map<String,Object> result = new HashMap<>();
        if(role != null){
            roleService.UpdateRole(role);
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/user/roleremove",method = RequestMethod.POST)
    @ResponseBody
    public Object roleRemove(@RequestBody String roleIds){
        Map<String,Object> result = new HashMap<>();

        if(roleIds != null){
            roleService.DeleteRoles(roleIds.split(","));
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/user/correlaterolepage")
    public String correlateRolePage(
            @RequestParam(value = "userid",required = true) String userId,Model model){
        model.addAttribute("userId",userId);
        return "sys/user/correlaterole";
    }

    @RequestMapping(value = "/user/rolelistbyuser",method = RequestMethod.GET)
    @ResponseBody
    public Object roleListByUserId(
            @RequestParam(value = "userid",required = true) String userId,
            @RequestParam(value = "limit", required=false) Integer pageSize,
            @RequestParam(value = "page", required=false) Integer currentPage){
        return roleService.findRolesByCorrelatedUser(userId,pageSize,currentPage);
    }

    @RequestMapping(value = "/user/correlaterole",method = RequestMethod.POST)
    @ResponseBody
    public Object correlateRole(@RequestBody UserRoleModel userRoleModel){
        Map<String,Object> result = new HashMap<>();
        if(userRoleModel.getAddIds().length > 0){
            roleService.correlationRoles(userRoleModel.getUserId(),userRoleModel.getAddIds());
        }
        if(userRoleModel.getDeleteIds().length > 0){
            roleService.uncorrelationRoles(userRoleModel.getUserId(),userRoleModel.getDeleteIds());
        }
        result.put("status","OK");
        return result;
    }

    @RequestMapping(value = "/role/correlatemenupage",method = RequestMethod.GET)
    public String correlationMenusPage(@RequestParam(value = "roleid") String roleId, Model model){
        model.addAttribute("roleId",roleId);
        model.addAttribute("domainId",domainId);
        return "sys/role/correlatemenu";
    }

    @RequestMapping(value = "/role/correlatemenu",method = RequestMethod.POST)
    @ResponseBody
    public Object correlationMenus(@RequestBody RoleMenuModel roleMenuModel){
        Map<String,Object> result = new HashMap<>();
        Integer insertNum = roleService.correlationMenus(
                roleMenuModel.getRoleId(),
                roleMenuModel.getAppId(),
                roleMenuModel.getMenuIds().toArray(new String[0]));
        if(insertNum.intValue() == roleMenuModel.getMenuIds().size()){
            result.put("status","OK");
        }else {
            result.put("status","error");
        }
        return result;
    }

    @RequestMapping(value = "/role/uncorrelatemenu",method = RequestMethod.POST)
    @ResponseBody
    public Object uncorrelationMenus(@RequestBody String roleId){
        Map<String,Object> result = new HashMap<>();
        Integer updateNum = roleService.uncorrelationMenus(roleId);
        if(updateNum.intValue() > 0){
            result.put("status","OK");
        }else {
            result.put("status","error");
        }
        return result;
    }
    /************************************ 角色管理 end ******************************************/



    /************************************ 菜单管理 start ******************************************/
    /**
     * 菜单管理页面
     * @return
     */
    @RequestMapping(value = "/menu/menumanage")
    public String menuManage(Model model){
        model.addAttribute("domainId",domainId);
        return "sys/menu/menumanage";
    }

    @RequestMapping(value = "/menu/pagelist")
    @ResponseBody
    public Object menuListByPage(
            @RequestParam(value = "appid", required = true) String appId,
            @RequestParam(value = "parentmenuid", required = true) String parentMenuId,
            @RequestParam(value = "limit", required = true) Integer pageSize,
            @RequestParam(value = "page", required = true) Integer currentPage){
        return menuService.findMenusByPage(appId,parentMenuId,pageSize,currentPage-1);
    }

    @RequestMapping(value = "/menu/menulist",method = RequestMethod.GET)
    @ResponseBody
    public Object menuList(){
        Subject subject = SecurityUtils.getSubject();
        String userName = subject.getPrincipal().toString();
        List<MenuCombination> resultMenus = null;
        if(Objects.equals("admin",userName)){
            resultMenus = menuService.findMenuList(domainId);
        }else {
            Set<String> roleIds = roleService.findRolesByUserName(userName);
            resultMenus = menuService.findMenuListForRole(roleIds, domainId);
        }


        return resultMenus;
    }

    @RequestMapping(value = "/menu/menutree",method = RequestMethod.GET)
    @ResponseBody
    public Object menuTree(
            @RequestParam(value = "roleid", required = true) String roleId,
            @RequestParam(value = "appid", required = true) String appId){
        return menuService.findMenuListForTree(roleId,appId);
    }

    @RequestMapping(value = "/menu/parentid")
    @ResponseBody
    public String findParentIdByMenuId(@RequestParam(value ="menuid",required = true) String menuId){
        return menuService.findParentIdByMenuId(menuId);
    }

    @RequestMapping(value = "/menu/menuadd")
    public String menuAdd(@RequestParam(value = "appid",required = true) String appId,
                          @RequestParam(value = "parentid",required = true)String parentId, Model model){
        model.addAttribute("appId",appId);
        model.addAttribute("parentId",parentId);
        return "sys/menu/menuedit";
    }

    @RequestMapping(value = "/menu/menucreate",method = RequestMethod.POST)
    @ResponseBody
    public Object menuCreate(@ModelAttribute("menu") MenuModel menu, @RequestParam(value = "appid") String appId){
        Map<String,Object> result = new HashMap<>();
        if(menu != null){
            menuService.createMenu(appId,menu);
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/menu/menuremove",method = RequestMethod.POST)
    @ResponseBody
    public Object deleteMenByIds(@RequestBody(required = true) String menuIds){
        Map<String,Object> result = new HashMap<>();
        String[] menuIdArray = menuIds.split(",");
        Integer resultIndex = menuService.deleteMenByIds(menuIdArray);
        if(resultIndex > 0){
            result.put("status","OK");
        }else {
            result.put("status","error");
        }
        return result;
    }
    /************************************菜单管理 end******************************************/



    /************************************应用管理 start******************************************/
    @RequestMapping(value = "/app/applist", method = RequestMethod.GET)
    @ResponseBody
    public Object AppList(){
        return appService.findAppList();
    }

    @RequestMapping(value = "/app/appadd")
    public String appAdd(){
        return "sys/app/appedit";
    }

    @RequestMapping(value = "/app/appcreate",method = RequestMethod.POST)
    @ResponseBody
    public Object appCreate(@ModelAttribute("app") AppModel app){
        Map<String,Object> result = new HashMap<>();
        if(app != null){
            appService.createApp(app);
            result.put("status","OK");
            return result;
        }
        result.put("status","error");
        return result;
    }

    @RequestMapping(value = "/app/appremove",method = RequestMethod.POST)
    @ResponseBody
    public Object deleteAppById(@RequestBody(required = true) String menuId){
        Map<String,Object> result = new HashMap<>();
        Integer resultIndex = appService.deleteApp(menuId);
        if(resultIndex > 0){
            result.put("status","OK");
        }else {
            result.put("status","error");
        }
        return result;
    }
    /************************************应用管理 end******************************************/



    /************************************字典管理 start***************************************/
    @RequestMapping(value = "/dict/dictmanage",method = RequestMethod.GET)
    public String dictManage(){
        return "sys/dict/dictmanage";
    }

    @RequestMapping(value = "/dict/dictlist",method = RequestMethod.GET)
    @ResponseBody
    public Object dictListByPage(
        @RequestParam(value = "limit", required = true) Integer pageSize,
        @RequestParam(value = "page", required = true) Integer currentPage,
        @RequestParam(value = "dictType", required = false) String dictType){
        Map<String, Object> result = new HashMap<>();
        List<DictionaryModel> dictList
                = dictionaryService.findDictionarysByPage(dictType,pageSize,currentPage);
        result.put("count", dictList.size());
        result.put("data", dictList);
        result.put("code", 0);
        result.put("msg", "");
        return result;
    }
    /************************************字典管理 end***************************************/
}
